﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Linq;
using t_205_verk_hopur_12.Helpers;

namespace t_205_verk_hopur_12.Models
{
    public class VideoRepository : t_205_verk_hopur_12.Models.IVideoRepository
    {
        private MittTVDataContext db = new MittTVDataContext();

        // To get all videos belonging to a particular channel
        public IQueryable<Video> GetVideosByChannelID(int channelID)
        {
            return from video in db.Videos
                   where video.ChannelID == channelID
                   select video;
        }

        public IQueryable<Video> GetApprovedVideosByChannelID(int channelID)
        {
            return from video in db.Videos
                   where video.ChannelID == channelID
                   && (video.State == 4 || video.State == 2)
                   select video;
        }

        // To get a particular video
        public Video GetVideoByID(int videoID)
        {
            return (from video in db.Videos
                    where video.ID == videoID
                    select video).SingleOrDefault();
        }
        
        // To add a new Video
        public void AddVideo(Video newVideo)
        {
            db.Videos.InsertOnSubmit(newVideo);
        }

        // Saving changes to database, Persistence
        public void Save()
        {
            db.SubmitChanges();
        }

        // Delete a video
        public void Delete(Video newVideo)
        {
            db.Videos.DeleteOnSubmit(newVideo);
        }

        // Votes on a specific video
        public void VoteVideo(int videoID, int userID, int vote)
        {
            VideoVote videoVote = new VideoVote();

            Video video = GetVideoByID(videoID);
            video.Rating += vote; // this works with negative numbers as well

            videoVote.VideoID = videoID;
            videoVote.UserID = userID;
            videoVote.Vote = vote;

            db.VideoVotes.InsertOnSubmit(videoVote);
            Save();
        }

        // Check if the user has voted for a video
        public bool HasUserVotedVideo(VideoVote videoVote)
        {
            return (from cv in db.VideoVotes
                    where cv == videoVote
                    select cv).Count() >= 1;
        }

        // Gets a list of the most popular videos by channel
        public IQueryable<ScheduleVideo> GetPopularVideoByChannel(int channelID)
        {
            var uniqueList =  from schedule in db.Schedules
                              where schedule.ChannelID == channelID
                              group schedule by schedule.VideoID into s
                              select new
                              {
                                  id = s.Max(i => i.ID)
                              };

            return (from schedule in db.Schedules
                    join video in db.Videos on schedule.VideoID equals video.ID into sb
                    where schedule.ChannelID == channelID
                    && uniqueList.Any(sInner => schedule.ID == sInner.id)
                    orderby schedule.Video.Rating descending
                    select new ScheduleVideo
                    {
                        ID = schedule.ID,
                        ChannelID = schedule.ChannelID,
                        VideoID = schedule.VideoID,
                        StartTime = schedule.StartTime,
                        EndTime = schedule.EndTime,
                        UserID = schedule.Video.UserID,
                        Title = schedule.Video.Title,
                        Description = schedule.Video.Description,
                        Rating = schedule.Video.Rating,
                        Embed = schedule.Video.Embed
                    }).Take(5);
        }
    }
}
